package cn.kattomy.shop.product.dao.impl;


import java.util.Date;
import java.util.List;

import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.hibernate.Query;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.search.FullTextQuery;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.hibernate.search.query.dsl.QueryBuilder;

import cn.kattomy.shop.base.dao.BaseDao;
import cn.kattomy.shop.image.vo.Image;
import cn.kattomy.shop.product.dao.ProductDao;
import cn.kattomy.shop.product.vo.Product;
import cn.kattomy.shop.utils.PageBean;

public class ProductDaoImpl extends BaseDao implements ProductDao {

	@Override
	public List<Product> queryHotProduct() {
		String hql = "FROM Product p WHERE p.is_hot = 1 ORDER BY p.pdate DESC";
//		ORDER BY p.pdate DESC LIMIT ?,?
		return getSession().createQuery(hql).setFirstResult(0).setMaxResults(10).list();
	}

	@Override
	public List<Product> queryNewProduct() {
		String hql = "FROM Product p ORDER BY p.pdate DESC";
		return getSession().createQuery(hql).setFirstResult(0).setMaxResults(10).list();
	}

	@Override
	public Product queryByPid(Integer pid) {
		return (Product) getSession().get(Product.class, pid);
	}

	@Override
	public int findCountByCid(Integer cid) {
		String hql = "SELECT count(*) FROM Product p WHERE p.categorySecond.category.cid = ?";
		Query query = getSession().createQuery(hql).setInteger(0, cid);
		List<Long> list = query.list();
		int result = ((Number)list.get(0)).intValue();
		return result;
	}

	@Override
	public List<Product> findByPageCid(Integer cid, int begin, int pageSize) {
//		SELECT p.* FROM category c, categorySecond cs, product p WHERE c.cid = cs.cid and cs.csid = p.csid and c.cid = ?
//		SELECT p FROM category c, categorySecond cs, product p WHERE c.cid = cs.category.cid and cs.csid = p.categorySecond.csid and c.cid = ?
		String hql = "SELECT p FROM Product p join p.categorySecond cs join cs.category c WHERE c.cid = ?";
		List<Product> list = getSession().createQuery(hql).setInteger(0, cid).setFirstResult(begin).setMaxResults(pageSize).list();
		return list;
	}

	@Override
	public int findCountByCsid(Integer csid) {
		String hql = "SELECT count(*) FROM Product p WHERE p.categorySecond.csid = ?";
		List<Long> list = getSession().createQuery(hql).setInteger(0, csid).list();
		int result = ((Number)list.get(0)).intValue();
		return result;
	}

	@Override
	public List<Product> findByPageCsid(Integer csid, int begin, int pageSize) {
		String hql = "SELECT p FROM Product p JOIN p.categorySecond cs WHERE cs.csid = ?";
		List<Product> list = getSession().createQuery(hql).setInteger(0, csid).setFirstResult(begin).setMaxResults(pageSize).list();
		return list;
	}

	@Override
	public int findCount() {
		String hql = "select count(*) from Product";
		List<Long> list = getSession().createQuery(hql).list();
		if (list != null && list.size() > 0) {
			return list.get(0).intValue();
		}
		return 0;
	}

	@Override
	public List<Product> findByPageNo(int begin, int pageSize) {
		String hql = "from Product order by pdate";
		List<Product> list = getSession().createQuery(hql).setFirstResult(begin).setMaxResults(pageSize).list();
		if (list != null && list.size() > 0) {
			return list;
		}
		return null;
	}

	@Override
	public void save(Product product) {
		getSession().save(product);
	}

	@Override
	public void delete(Product product) {
		getSession().delete(product);
	}

	@Override
	public void update(Product product) {
		getSession().update(product);
	}

	@Override
	public List<Product> findAll() {
		String hql = "From Product";
		return getSession().createQuery(hql).list();
	}

	@Override
	public void saveImage(Image image) {
		getSession().save(image);
	}

	@Override
	public double findImageCount() {
		String hql = "select count(*) from Image";
		List<Long> list = getSession().createQuery(hql).list();
		if (list != null && list.size() > 0) {
			return list.get(0).intValue();
		}
		return 0;
	}

	@Override
	public PageBean<Product> searchByKeyword(String keyword, Integer pageNo) {
		//通过当前事务的Session获取FullTextSession对象
		FullTextSession fts = Search.getFullTextSession(getSession());
		//获取特定类的特定QueryBuilder对象
	    QueryBuilder qb = fts.getSearchFactory().buildQueryBuilder().forEntity(Product.class).get();
	    //得到search query
	    org.apache.lucene.search.Query luceneQuery = qb.keyword().onFields("pname", "pdesc", "key_words").matching(keyword).createQuery();
	    FullTextQuery query = fts.createFullTextQuery(luceneQuery, Product.class);
	    
	    //分页信息
	    int pageSize = 12;
	    int begin = (pageNo - 1) * pageSize;
	    //分页类
	    PageBean<Product> pageBean = new PageBean<>(pageNo, pageSize);
	    int dataSize = query.getResultSize();
	    pageBean.setTotalItemNo(dataSize);
	    System.out.println(dataSize);
	    //分页查询
	    query.setFirstResult(begin);
	    query.setMaxResults(pageSize);
	    //封装分页数据
	    pageBean.setList(query.list());
	    
		return pageBean;
	}

	@Override
	public void createIndex() {
		FullTextSession fts = Search.getFullTextSession(getSession());
		
		fts.setFlushMode(FlushMode.MANUAL);
		fts.setCacheMode(CacheMode.IGNORE);
		
		int BATCH_SIZE = 1000;
		long startTime = new Date().getTime();
		//Scrollable results will avoid loading too many objects in memory
		ScrollableResults results = fts.createCriteria(Product.class).setFetchSize(BATCH_SIZE).scroll(ScrollMode.FORWARD_ONLY );
		int index = 0;
		while( results.next() ) {
		    index++;
		    fts.index( results.get(0) ); //index each element
		    if (index % BATCH_SIZE == 0) {
		        fts.flushToIndexes(); //apply changes to indexes
		        fts.clear(); //free memory since the queue is processed
		    }
		}
		
		long endTime = new Date().getTime();
		System.out.println("本次建立索引共用时" + (endTime - startTime));
		
	}

}
